/*
 *  Copyright (C) 2009  Peter Kist & Jan Ripke
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __input_mediator_types_h
#define __input_mediator_types_h 1

#include <OIS/OISKeyboard.h>

#include <mediator/Event.h>
#include <mediator/Interface.h>

namespace galaxy {
    namespace input {

#define MODULE_TYPE_INPUT_KEY      1
#define MODULE_TYPE_INPUT_MOUSE    2
#define MODULE_TYPE_INPUT_JOYSTICK 3

#define MODULE_SUBTYPE_INPUT_KEYPRESS   1
#define MODULE_SUBTYPE_INPUT_KEYRELEASE 2

#define MODULE_SUBTYPE_INPUT_MOUSEMOVE    1
#define MODULE_SUBTYPE_INPUT_MOUSEPRESS   2
#define MODULE_SUBTYPE_INPUT_MOUSERELEASE 3
#define MODULE_SUBTYPE_INPUT_MOUSECLICK   4


        /** This enum defines the possible actions that are mapped to the key that was pressed or
        * released.
        */
        typedef enum _keyaction {
            INPUT_KEYACTION_EXIT = 1,           /**< key that exists either the game state */
            INPUT_KEYACTION_KEY = 10,           /**< handle key as typed character */
            INPUT_KEYACTION_FORWARD = 20,       /**< key that moves entity forward */
            INPUT_KEYACTION_BACKWARD = 21,      /**< key that moves entity backward */
            INPUT_KEYACTION_LEFT = 22,          /**< key that rotates entity left */
            INPUT_KEYACTION_RIGHT = 23,         /**< key that rotates entity right */
            INPUT_KEYACTION_UP = 24,            /**< key that rotates entity up */
            INPUT_KEYACTION_DOWN = 25,          /**< key that rotates entity down */
            INPUT_KEYACTION_MENU_KEY = 100,     /**< key that translates to menu button click */
        } KeyAction;


        /** Input Event that contains the keycode, character and logical action for the key event.
        * (keypress or key release)
        */
        class KeyEvent: public mediator::Event {
        public:

            OIS::KeyCode   m_Key;         /**< KeyCode of event */
            unsigned int   m_Modifiers;   /**< key modifiers (alt,ctrl or shift) */
            unsigned int   m_Text;        /**< Text character */
            KeyAction      m_KeyAction; /**< logical action related to this event */

            KeyEvent () : Event () { };
            KeyEvent (KeyEvent& event) : Event (event) {
                m_Key = event.m_Key;
                m_Modifiers = 0;
                m_Text = event.m_Text;
                m_KeyAction = event.m_KeyAction;
            }
            KeyEvent(mediator::Category category, int type, int subtype) 
                : Event(category, type, subtype), m_Key(OIS::KC_UNASSIGNED), m_Modifiers(0),
                m_Text(0), m_KeyAction(INPUT_KEYACTION_KEY)
            { 
            };

            virtual Event * clone () { return new KeyEvent(*this); };
        };

        typedef enum _mousebuttonid {
            MOUSE_BUTTON_NONE = 0,
            MOUSE_BUTTON_LEFT = 1,
            MOUSE_BUTTON_MIDDLE = 2,
            MOUSE_BUTTON_RIGHT = 3,
        } MouseButton;

        class MouseEvent : public mediator::Event {
        public:

            MouseButton m_MouseButton;
            int         m_Xrel;
            int         m_Yrel;

            MouseEvent() : Event () { };
            MouseEvent(MouseEvent& event) : Event (event)
            {
                m_MouseButton = event.m_MouseButton;
                m_Xrel = event.m_Xrel;
                m_Yrel = event.m_Yrel;
            };
            MouseEvent(mediator::Category category, int type, int subtype) 
                : Event (category, type, subtype) 
            {
            };
            virtual Event * clone () { return new MouseEvent (*this); };
        };

    } // namespace input
} // namespace galaxy



#endif // __gfx_mediator_types_h
